<template>
  <div class="app">
    <header class="app-header">
      <ui5-shellbar primary-title="UI5 Web Components Vue Sample Application" />
    </header>

    <ui5-tabcontainer collapsed>
      <ui5-tab text="Todos" />
    </ui5-tabcontainer>

    <section class="app-content">
      <div class="create-todo-wrapper">
        <ui5-input
          placeholder="Type a task..."
          ref="todoInput"
          class="add-todo-element-width"
          id="add-input"
        />
        <ui5-date-picker
          format-pattern="dd/MM/yyyy"
          class="add-todo-element-width"
          ref="todoDeadline"
          id="date-picker"
        />
        <ui5-button
          class="add-todo-element-width"
          ref="addButton"
          design="Emphasized"
          @click="handleAdd"
        >
          Add Todo
        </ui5-button>
      </div>

      <div class="list-todos-wrapper">
        <ui5-panel
          class="list-todos-panel"
          header-text="Incompleted Tasks"
          :collapsed="panelCollapsed()"
        >
          <TodoList
            :todos="todos"
            @selection-change="handleDone"
            @item-deleted="handleRemove"
            @item-edit="handleEdit"
          >
          </TodoList>
        </ui5-panel>

        <ui5-panel
          class="list-todos-panel"
          header-text="Completed Tasks"
          :collapsed="donePanelCollapsed()"
        >
          <TodoList
            :todos="doneTodos"
            @selection-change="handleUndone"
            @item-deleted="handleRemove"
            @item-edit="handleEdit"
          >
          </TodoList>
        </ui5-panel>
      </div>
    </section>

    <ui5-dialog header-text="Edit Todo" ref="editDialog">
      <div class="dialog-content">
        <div class="edit-wrapper">
          <ui5-label>Title:</ui5-label>
          <ui5-textarea
            class="title-textarea"
            show-exceeded-text
            maxlength="24"
            :value="todoBeingEdittedText"
            ref="titleEditInput"
          >
          </ui5-textarea>
        </div>

        <div class="edit-wrapper date-edit-fields">
          <ui5-label>Date:</ui5-label>
          <ui5-date-picker
            format-pattern="dd/MM/yyyy"
            :value="todoBeingEdittedDate"
            ref="dateEditInput"
          ></ui5-date-picker>
        </div>
      </div>
      <div class="dialog-footer" data-ui5-slot="footer">
        <ui5-button class="dialog-footer-btn--cancel" design="Transparent" @click="cancelEdits"
          >Cancel</ui5-button
        >
        <ui5-button class="dialog-footer-btn--save" design="Emphasized" @click="saveEdits"
          >Save</ui5-button
        >
      </div>
    </ui5-dialog>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  import TodoList from './todo/TodoList.vue';

  interface Todo {
    text: string;
    id: string;
    deadline: string;
    done: boolean;
  }

  const todos = ref<Todo[]>([
    { text: 'Get some carrots', id: 'i1', deadline: '27/7/2018', done: false },
    { text: 'Do some magic', id: 'i2', deadline: '22/7/2018', done: false },
    { text: 'Go to the gym', id: 'i3', deadline: '24/7/2018', done: false },
    { text: 'Buy milk', id: 'i4', deadline: '30/7/2018', done: false },
  ]);
  const doneTodos = ref<Todo[]>([
    { text: 'Eat some fruits', id: 'i5', deadline: '29/7/2018', done: true },
  ]);

  const todoBeingEdittedText = ref('');
  const todoBeingEdittedDate = ref('');
  const selectedEditTodo = ref('');

  const todoInput = ref<HTMLInputElement>();
  const todoDeadline = ref<InstanceType<typeof HTMLInputElement>>();
  const addButton = ref<InstanceType<typeof HTMLButtonElement>>();
  const editDialog = ref<HTMLElement & { open: boolean; show(): void; close(): void }>();
  const titleEditInput = ref<HTMLTextAreaElement>();
  const dateEditInput = ref<InstanceType<typeof HTMLInputElement>>();

  function handleAdd() {
    todos.value = [
      ...todos.value,
      {
        text: todoInput.value?.value || '',
        id: (todos.value.length + 1).toString(),
        deadline: todoDeadline.value?.value || '',
        done: false,
      },
    ];
  }

  function handleDone(event: { detail: { selectedItems: Element[] } }) {
    const selectedItem = event.detail.selectedItems[0];
    const selectedId = selectedItem.getAttribute('data-key');
    const newlySelected = todos.value.find((todo) => selectedId === todo.id.toString());
    if (newlySelected) {
      newlySelected.done = true;
      doneTodos.value.push(newlySelected);
      todos.value = todos.value.filter((todo) => selectedId !== todo.id.toString());
    }
  }

  function handleUndone(event: { detail: { selectedItems: Element[] } }) {
    const selectedItems = event.detail.selectedItems;
    const selectedIds = selectedItems.map((item) => item.getAttribute('data-key'));
    const newlyDeselected = doneTodos.value
      .filter((todo) => selectedIds.indexOf(todo.id.toString()) === -1)
      .map((item) => ({ ...item, done: false }));
    doneTodos.value = doneTodos.value.filter(
      (todo) => selectedIds.indexOf(todo.id.toString()) > -1,
    );
    todos.value = [...todos.value, ...newlyDeselected];
  }

  function handleRemove(item: { id: string | number }) {
    todos.value = todos.value.filter((todo) => todo.id.toString() !== item.id.toString());
    doneTodos.value = doneTodos.value.filter((todo) => todo.id.toString() !== item.id.toString());
  }

  function handleEdit(item: { id: string | number }) {
    let todoObj = todos.value.find((todo) => todo.id.toString() === item.id.toString());
    if (!todoObj) {
      todoObj = doneTodos.value.find((todo) => todo.id.toString() === item.id.toString());
    }
    if (todoObj) {
      todoBeingEdittedText.value = todoObj.text;
      todoBeingEdittedDate.value = todoObj.deadline;
      selectedEditTodo.value = todoObj.id;
      if (editDialog.value) editDialog.value.open = true;
    }
  }

  function saveEdits() {
    const edittedText = titleEditInput.value?.value || '';
    const edittedDate = dateEditInput.value?.value || '';
    todos.value = todos.value.map((todo) => {
      if (todo.id === selectedEditTodo.value) {
        todo.text = edittedText;
        todo.deadline = edittedDate;
      }
      return todo;
    });
    doneTodos.value = doneTodos.value.map((todo) => {
      if (todo.id === selectedEditTodo.value) {
        todo.text = edittedText;
        todo.deadline = edittedDate;
      }
      return todo;
    });
    if (editDialog.value) editDialog.value.open = false;
  }

  function cancelEdits() {
    if (editDialog.value) editDialog.value.open = false;
  }

  function panelCollapsed() {
    return !todos.value.length ? true : undefined;
  }
  function donePanelCollapsed() {
    return !doneTodos.value.length ? true : undefined;
  }
</script>

<style>
  html,
  body {
    padding: 0;
    margin: 0;
    height: 100%;
    font-family:
      -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',
      'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  .app {
    height: 100%;
    background-color: var(--sapBackgroundColor);
  }

  .header-toolbar {
    position: sticky;
    z-index: 42;
    background-color: rgba(255, 255, 255, 0.6);
    box-shadow: 0 4px 5px -5px #0a6ed1;
  }

  .app-header-logo {
    height: 2rem;
    max-height: 2rem;
  }

  .app-title {
    margin-inline-start: 1rem;
  }

  .app-content {
    padding: 0 1rem;
    width: calc(100% - 2rem);
  }

  .app-bar-theming-popover {
    width: 250px;
  }

  .create-todo-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    margin: 2rem 0;
    box-sizing: border-box;
    background-color: var(--sapObjectHeader_Background);
  }

  .list-todos-wrapper {
    margin: 2rem 0;
  }

  .list-todos-panel {
    margin: 2rem 0;
  }

  .li-content-actions {
    display: flex;
  }

  .add-todo-element-width {
    width: auto;
  }

  #add-input {
    flex: auto;
  }

  #date-picker {
    margin: 0 0.5rem 0 0.5rem;
  }

  .li-content {
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: center;
  }

  .li-content-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .edit-btn {
    margin-inline-end: 1rem;
  }

  .dialog-content {
    max-width: 320px;
    padding: 2rem 2rem;
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    padding: 0.25rem 0.25rem 0 0.25rem;
    border-top: 1px solid #d9d9d9;
  }

  .dialog-footer-btn--cancel {
    margin-inline-end: 0.25rem;
  }

  .title-textarea {
    height: 100px;
    display: inline-block;
    width: 100%;
  }

  .date-edit-fields {
    display: flex;
    flex-direction: column;
    margin-top: 1rem;
  }

  @media (max-width: 600px) {
    .create-todo-wrapper {
      flex-direction: column;
    }

    .add-todo-element-width {
      width: 100%;
    }

    #date-picker {
      margin: 0.5rem 0 0.5rem 0;
    }
  }

  .app-bar-profile-popover {
    width: 250px;
  }

  #settings-dialog {
    max-width: 300px;
  }

  .dialog-button {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.625rem;
    margin-bottom: -0.425rem;
  }

  .profile-settings,
  .help-header {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
  }

  .profile-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-inline-start: 1rem;
  }

  .app-header-logo {
    height: 2rem;
  }

  .profile-settings-list {
    margin-top: 1.25rem;
  }

  .aligned {
    align-items: center;
    gap: 0.725rem;
  }

  .help-dialog-text {
    font-size: 0.875rem;
  }

  .profile-rtl-switch {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  #header-title-align {
    margin: 1rem 0;
    gap: 0.225rem;
  }

  #header-logo-align {
    margin: 0.225rem 3.225rem 0.225rem 0;
    align-items: center;
    gap: 0.435rem;
  }

  #help-dialog::part(header) {
    justify-content: flex-start;
  }
</style>
